/*
 * $Id: PDFTest.java,v 1.4 2001/11/16 15:26:04 ezb Exp $
 *
 * $Date: 2001/11/16 15:26:04 $
 *
 * Copyright (C) 2001  Eric Z. Beard, ericzbeard@hotmail.com
 * 
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 */
package gnu.jpdf;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

import javax.swing.*;

import vue.panneau3.util.Util;

import java.io.*;

/**
 * <p>The purpose of this class is to test all functionality of the 
 * gnu.jpdf package and serve as a demonstration of how to use the 
 * library.</p>
 *
 * <p>This library produces pdf format files and can display and print 
 * them in a java Graphics context by extending java.awt.Graphics and 
 * java.awt.PrintJob.  The pdf file itself is not viewed, but an  
 * identical copy made with the same methods that constructed the 
 * pdf file.  See the code or the tutorial for an example</p>
 *
 * @author Eric Z. Beard 
 *         <a href = "mailto:ericzbeard@hotmail.com">ericzbeard@hotmail.com</a>
 * @author $Author: ezb $
 * @version $Revision: 1.4 $
 */
public class PDFTest extends JFrame implements ActionListener
{
	private static final long serialVersionUID = 1L;

	/** Entered on the command line after '-pdf' */
	private static String outputPdfFile ="montest.pdf";

	/** Entered on the command line after '-img' */
	private static Image sampleImageFile = null;

	/** Not yet supported - test without a window */
	private static boolean noWindow;

	/** Main content pane */
	private JPanel pane = new JPanel();

	/** All sizes will be derived from the desired pdf document size */  
	public Dimension documentDimension;

	private int currentPage;

	private PDFJob job;

	private boolean pdfDocumentAlreadyDone;

	/** 
	 * A JPanel used for drawing the document on the screen 
	 *
	 * The source is included in this file at the bottom
	 */
	private TestPanel drawingArea;

	/** The menu bar */
	private TestMenuBar menuBar;

	public PDFTest(String outputPdfFile, Image sampleImageFile, boolean noWindow) 
	{
		// First see if the file path is valid
		File file = null;
		PDFTest.sampleImageFile=sampleImageFile;
		FileOutputStream fileOutputStream = null;
		try 
		{
			file = new File(outputPdfFile);
			fileOutputStream = new FileOutputStream(file);
		}
		catch (Exception e) 
		{
			System.err.println("Error!! - Invalid output file path: " + outputPdfFile);
			usage();
//			System.exit(1);
		}
		
		// Handle window closing
		addWindowListener(new WindowAdapter() 
		{
			public void windowClosing(WindowEvent e) 
			{dispose();}
		});

		Container contentPane = getContentPane();

		pane.setLayout(new BorderLayout());

		// Add the menubar
		menuBar = new TestMenuBar(this);
		setJMenuBar(menuBar);

		// Get the Graphics object for pdf writing
		Graphics pdfGraphics = null;
		job = new PDFJob(fileOutputStream);
		pdfGraphics = job.getGraphics();
		Dimension d = job.getPageDimension();
		documentDimension = d;

		// Finish setting up the window and bring to front
		int w = (int)d.getWidth();
		int h = (int)d.getHeight();

		drawingArea = new TestPanel();

		// Put the drawing area in a scroll pane
		JScrollPane scrollPane = new JScrollPane(drawingArea, 
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);

		// Set the preferred size bigger than the scroll pane so the bars show up
		drawingArea.setPreferredSize(new Dimension(1000, 1000));

		pane.add(scrollPane, "Center");

		contentPane.add(pane);

		setTitle("PDF Test Application");

		// Set the location and size of the window and show it
		//Toolkit toolkit = Toolkit.getDefaultToolkit();
		//Dimension screenSize = toolkit.getScreenSize();
		setLocation(50, 50);
		setSize(w, h/2);
		setVisible(true);
		toFront();

		doFirstPage(pdfGraphics);   
		currentPage = 1;

		if (fileOutputStream != null) 
		{
			try 
			{
				fileOutputStream.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			fileOutputStream = null;
		}
		drawingArea.repaint();
		pane.revalidate();
	} // end constructor

	private void doFirstPage(Graphics pdfGraphics) 
	{
		Dimension d = documentDimension;
		// Get the graphics object for screen drawing
		Image img = drawingArea.createImage((int)d.getWidth(),(int)d.getHeight());
		if (img == null) 
		{
			System.out.println("Error!! - drawing image is null");
//			System.exit(1);
		}

		drawingArea.setImage(img);
		Graphics javaGraphics = img.getGraphics();    

		// Now we have two Graphics objects - one for java Graphics to 
		// draw to the screen , another to write 
		// to the pdf file.  We'll use the same methods to act on both 
		// objects, and (theoretically) the results should be identical.
		// If 'Print' is selected from the menu, the same methods wi
		// act on a Graphics object from the java.awt.PrintJob    

		doTest(javaGraphics, d);
		javaGraphics.dispose();

		// The whole pdf doc will be written when the program starts
		if ((!pdfDocumentAlreadyDone) && (pdfGraphics != null)) 
		{
			doTest(pdfGraphics, d);
			pdfGraphics.dispose();

			pdfGraphics = job.getGraphics();
			doSecondPageTest(pdfGraphics);
			pdfGraphics.dispose();
			job.end();
		}

		// The same methods (such as 'job.end()') are called on the pdf job 
		// as on a print job, so this could be abstracted further to use the 
		// same code on both jobs
		currentPage = 1;

		drawingArea.repaint();
		drawingArea.revalidate();
	}

	/**
	 * <p>Very basic action handler - a more robust app would use 
	 * Action objects</p>
	 *
	 * @param e an <code>ActionEvent</code> value
	 */
	public void actionPerformed(ActionEvent e) 
	{
		Object source = e.getSource();    
		if (source == menuBar.close) 
		{dispose();}        
		if (source == menuBar.printer) 
		{
			printPdf();
			return;
		}
		if (source == menuBar.helpTopics)
		{
			System.out.println("Help..");
			showHelp();
			return;
		}
		if (source == menuBar.viewFirstPage) 
		{
			if (currentPage != 1) 
			{
				doFirstPage(null);
				return;
			}
		}
		if (source == menuBar.viewSecondPage)
		{
			if (currentPage != 2) 
			{
				doSecondPage();
				return;
			}
		}
	}

	/**
	 * <p>Show a help dialog - it would be good to use text from 
	 * a tutorial that sits in the docs directory</p>
	 *
	 */
	private void showHelp() 
	{new HelpFrame();}

	/**
	 * <p>Gets a print job and uses the same drawing methods that 
	 * were used on the other Graphics objects to print the document</p>
	 *
	 */
	private void printPdf() 
	{
		System.out.println("Printing..");
		JobAttributes jobAttributes = new JobAttributes(); 
		//jobAttributes.setDialog(JobAttributes.DialogType.NONE); 
		// CRAP!! - This doesn't work with jdk1.2.2 - fix it
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		PrintJob pjob=toolkit.getPrintJob(this, "PDF Test Print", jobAttributes,  null); 
		if(pjob != null) 
		{  
			Graphics printGraphics = pjob.getGraphics(); 
			if (currentPage == 1) 
			{
				doTest(printGraphics, documentDimension); 
				printGraphics.dispose();
				pjob.end(); 
			}
			else 
			{
				doSecondPageTest(printGraphics);
				printGraphics.dispose();
				pjob.end();
			}
		} 
		else 
		{ System.err.println("Can't print: printjob null"); } 
	}

	/**
	 * <p>This method accepts any Graphics object and draws to it.  It 
	 * can be a java Graphics object for drawing to the screen, a pdf 
	 * graphics object for constructing a pdf object, or a print job 
	 * graphics object.  The goal is to make all three look exactly the 
	 * same, along with how the document looks when opened in Acrobat 
	 * Reader and printed from Acrobat Reader - so it's actually 5 things 
	 * that should ultimately look exactly the same, all constructed with 
	 * the same set of methods</p>
	 *
	 * <p>This method should provide programmers with a good basis 
	 * for using the BoundingBox class, if they choose to do so.  It is by 
	 * no means necessary, as it only makes layout on a fixed dimension 
	 * canvas easier.  The point of the pdf graphics library is to use 
	 * the same drawing methods used in applets and applications</p>
	 *
	 * @param g a <code>Graphics</code> object to draw to
	 * @param d a <code>Dimension</code> object, the size of the document
	 */
	private void doTest(Graphics g, Dimension d) 
	{
		g.setColor(Color.white);
		g.fillRect(0,0,d.width, d.height);
		g.setColor(Color.black);
		/* Point boxUpperLeft = new Point(60, 60);
    Dimension boxSize  = new Dimension(200, 200);
    Font f = new Font("TimesRoman", Font.PLAIN, 14);
    g.setFont(f);
    FontMetrics fm = g.getFontMetrics(f);
    BoundingBox box = new BoundingBox(boxUpperLeft, boxSize);
    String string = "Hello World! this is a really long string";
    int padding = 10;
    BoundingBox child = null;
    try { 
      child = box.getStringBounds(string,
                                  BoundingBox.HORIZ_ALIGN_CENTER,
                                  BoundingBox.VERT_ALIGN_BOTTOM,
                                  fm, 
                                  padding);
    }
    catch (StringTooLongException stle) {
      // A more robust app might just cut off the end of the string or 
      // prevent the string from ever being too long or break it into 
      // pieces and create a new PDFPage (by getting a new graphics object)
      // and continue the document
      stle.printStackTrace();
      return;
    }

    g.drawRect(60, 60, 200, 200);
    g.drawRect((int)child.getLocation().getX() + 60,
               (int)child.getLocation().getY() + 60,
               (int)child.getSize().getWidth(),
               (int)child.getSize().getHeight());
    Point p = child.getDrawingPoint();
    int x = (int)p.getX();
    int y = (int)p.getY();
    // Draw the baseline
    g.drawLine(x, y, x + ((int)child.getSize().getWidth() - padding*2), y);

    try {
      child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_CENTER);
    }
    catch (StringTooLongException stle) {
      stle.printStackTrace();
      return;
    }

    //drawHeader(g, d);
    //drawBody(g, d);

    // Draw Hello world in a nested box
    BoundingBox b1 = new BoundingBox(new Point(300, 60), 
				     new Dimension(200, 200));
    g.drawRect((int)b1.getAbsoluteLocation().getX(), 
               (int)b1.getAbsoluteLocation().getY(), 
               (int)b1.getSize().getWidth(),
               (int)b1.getSize().getHeight());
    BoundingBox b2 = new BoundingBox(new Point(10, 10), 
				     new Dimension(100, 100));
    b1.add(b2);        
    g.drawRect((int)b2.getAbsoluteLocation().getX(), 
               (int)b2.getAbsoluteLocation().getY(), 
               (int)b2.getSize().getWidth(),
               (int)b2.getSize().getHeight());

    try {    
      BoundingBox b3 = b2.getStringBounds(string,
                                        BoundingBox.HORIZ_ALIGN_CENTER,
                                        BoundingBox.VERT_ALIGN_BOTTOM,
                                        fm, 
                                        padding);
      g.drawRect((int)b3.getAbsoluteLocation().getX(), 
               (int)b3.getAbsoluteLocation().getY(), 
               (int)b3.getSize().getWidth(),
               (int)b3.getSize().getHeight());

      Point pt = b3.getDrawingPoint();
      int px = (int)pt.getX();
      int py = (int)pt.getY();
      b3.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_CENTER); 
    }
    catch (StringTooLongException stle) {
      stle.printStackTrace();
    }*/
		drawStringsInBox(g);
		drawSampleImage(g, d);
	} // end doTest

	/**
	 * Describe <code>drawStringsInBox</code> method here.
	 *
	 * @param g a <code>Graphics</code> value
	 */
	private void drawStringsInBox(Graphics g) 
	{
		g.setColor(Color.black);
		/*BoundingBox box = new BoundingBox(new Point(20, 300), 
                                      new Dimension(250, 250));
    g.drawRect((int)box.getAbsoluteLocation().getX(),
               (int)box.getAbsoluteLocation().getY(),
               (int)box.getSize().getWidth(),
               (int)box.getSize().getHeight());
    Font f = new Font("Helvetica", Font.PLAIN, 12);
    g.setFont(f);
    FontMetrics fm = g.getFontMetrics();
    String line1 = "Line 1";
    String line2 = "Line 2";
    String line3 = "Line 3 realllllly loooooong   .h gkjhg kjh gkjh gkjhg kjhg kjhg kjh gk jbhg";
    int padding = 5;

    BoundingBox child = null;
    try {
      child = box.getStringBounds(line1,
                                  BoundingBox.HORIZ_ALIGN_LEFT,
                                  BoundingBox.VERT_ALIGN_TOP,
                                  fm, 
                                  padding);
      child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_LEFT);
    }
    catch (StringTooLongException stle) {
      stle.printStackTrace();
      return;
    }
    box.subtract(child, BoundingBox.SUBTRACT_FROM_BOTTOM);

    try {
      child = box.getStringBounds(line2,
                                BoundingBox.HORIZ_ALIGN_LEFT,
                                BoundingBox.VERT_ALIGN_TOP,
                                fm, 
                                padding);
      child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_LEFT);
    }
    catch (StringTooLongException stle) {
      stle.printStackTrace();
      return;
    }

    box.subtract(child, BoundingBox.SUBTRACT_FROM_BOTTOM);

    try {
      child = box.getStringBounds(line3,
                                BoundingBox.HORIZ_ALIGN_LEFT,
                                BoundingBox.VERT_ALIGN_TOP,
                                fm, 
                                padding);
      child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_LEFT);
    }
    catch (StringTooLongException stle) {
      stle.printStackTrace();
      return;
    }
    box.subtract(child, BoundingBox.SUBTRACT_FROM_BOTTOM);

    try {
      child = box.getStringBounds(line1,
                                BoundingBox.HORIZ_ALIGN_RIGHT,
                                BoundingBox.VERT_ALIGN_BOTTOM,
                                fm, 
                                padding);
      child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_RIGHT);
      box.subtract(child, BoundingBox.SUBTRACT_FROM_TOP);

      child = box.getStringBounds(line2,
                                BoundingBox.HORIZ_ALIGN_RIGHT,
                                BoundingBox.VERT_ALIGN_BOTTOM,
                                fm, 
                                padding);
      child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_RIGHT);
      box.subtract(child, BoundingBox.SUBTRACT_FROM_TOP);

      child = box.getStringBounds(line3,
                                BoundingBox.HORIZ_ALIGN_RIGHT,
                                BoundingBox.VERT_ALIGN_BOTTOM,
                                fm, 
                                padding);
      child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_RIGHT);
      box.subtract(child, BoundingBox.SUBTRACT_FROM_TOP);
    }
    catch (StringTooLongException stle) {
      stle.printStackTrace();
      return;
    }*/

	} // end drawStringsInBox

	/**
	 * Describe <code>drawSampleImage</code> method here.
	 *
	 * @param g a <code>Graphics</code> value
	 * @param d a <code>Dimension</code> value
	 */
	private void drawSampleImage(Graphics g, Dimension d) 
	{
		try 
		{
			//Toolkit toolkit = Toolkit.getDefaultToolkit();
			Image img =PDFTest.sampleImageFile ;
			
//			Graphics gNew = new BufferedImage(
//					(int)documentDimension.getWidth()-10,
//					(int) (img.getHeight(drawingArea)*documentDimension.getWidth()/img.getWidth(drawingArea)),
//					BufferedImage.TYPE_INT_RGB
//					)
//			.getGraphics() ;
//			
//			gNew.drawImage(img,0,0,
//					(int)documentDimension.getWidth()-10,
//					(int) (img.getHeight(drawingArea)*documentDimension.getWidth()/img.getWidth(drawingArea)),
//					drawingArea) ;
//			
//			
//			
//			
//			Image img2 = Util.getImage() ;
			
			MediaTracker tracker = new MediaTracker(drawingArea);
			tracker.addImage(img, 0);
			try 
			{
				tracker.waitForID(0);
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			/* bazsoft 
      g.drawImage(img, 300, 300, 
                  img.getWidth(drawingArea), 
                  img.getHeight(drawingArea), 
                  Color.green, 
                  drawingArea);
			 */
			
			
//			G((Graphics2D)(img.getGraphics())).scale(0.5f, 0.5f) ;
			
			
			float combienDeFoisPlusPetit = 1 ;
			
			combienDeFoisPlusPetit = (float)documentDimension.getWidth()/img.getWidth(drawingArea) ;
//			System.out.println(combienDeFoisPlusPetit+" de fois plus petit" + " width = "+documentDimension.getWidth()+" sur "+img.getWidth(drawingArea));
			
//			Graphics2D g2d = (Graphics2D) g;
			
			String titre = "un titre" ;
			g.setFont(new Font(g.getFont().getFontName(),Font.BOLD,20)) ;
			
			
			FontMetrics fontMetrics = g.getFontMetrics();
			int longueur = fontMetrics.stringWidth(titre);
//			int hauteur = fontMetrics.getHeight();
			g.drawString(titre, (int)((documentDimension.getWidth()-longueur)/2), 40) ;
			
			g.drawImage(img, 10, 200, 
//					img.getWidth(drawingArea), 
//					img.getHeight(drawingArea),
					(int)documentDimension.getWidth()-5,
					(int) (img.getHeight(drawingArea)*combienDeFoisPlusPetit)-3,
//					20,20,
					
					drawingArea);
		}
		catch (Exception e) 
		{
			e.printStackTrace();
		}
	}

	private void doSecondPage() 
	{
		Dimension d = documentDimension;
		// Get the graphics object for screen drawing
		Image img = drawingArea.createImage((int)d.getWidth(),
				(int)d.getHeight());
		if (img == null)
		{
			System.out.println("Error!! - drawing image is null");
//			System.exit(1);
		}

		drawingArea.setImage(img);
		Graphics javaGraphics = img.getGraphics();    

		doSecondPageTest(javaGraphics);
		javaGraphics.dispose();

		currentPage = 2;
		drawingArea.repaint();
		drawingArea.revalidate();
	}

	private void doSecondPageTest(Graphics g) 
	{
		g.setColor(Color.white);
		g.fillRect(0,0,documentDimension.width, documentDimension.height);
		g.setColor(Color.black);
		// test drawLine()
		/* g.drawLine(10,10,50,50);

    // test drawRect()
    g.drawRect(30,10,10,10);

    // test fillRect()
    g.fillRect(30,90,10,10);

    // test drawPolygon()
    int xp[] = new int[] {10,10,20,15,20};
    int yp[] = new int[] {50,60,60,55,50};
    int np = xp.length;
    g.drawPolygon(xp,yp,np);

    // test drawPolygon()
    xp = new int[] {60,60,70,65,70};
    yp = new int[] {80,90,90,85,80};
    np = xp.length;
    g.drawPolyline(xp,yp,np);

    // test fillPolygon()
    xp = new int[] {60,60,70,65,70};
    yp = new int[] {50,60,60,55,50};
    np = xp.length;
    g.fillPolygon(xp,yp,np);

    // Now some text
    g.setFont(new Font("SansSerif",Font.PLAIN,12));
    g.drawString("This is a simple string",10,120);

    g.drawString("This is a (complex) string",10,130);

    g.drawString("(complex) string (with ( (multiple brackets ))",10,140);

    // Now some arcs - first test is with a square
    g.drawRect(200, 60, 50, 50);                // rectangle
    g.drawLine(200, 60,250,110);                // join both corners
    g.drawLine(200,110,250, 60);
    g.drawLine(200, 85,225, 60);                // this should be a chord
    g.drawArc( 200, 60, 50, 50, 45,180);        // the arc


    // June 20, 2001 ezb - Looks like ovals work as expected
    g.drawArc(100, 400, 100, 200, 0, 360);

    g.drawOval(200, 400, 100, 200);

    g.fillOval(300, 400, 100, 200);

    // These two tests act on a rectangular region (ie width != height)
    // Now the interesting thing is that they don't fit the arc within
    // the rectangle, but act on the width. This - by accident - matches the
    // way the Linux JDK operates...

    // Now the same test, but with a rectangle
    g.drawRect(300,50,80,40);
    g.drawLine(300,50,380,90);
    g.drawLine(300,90,380,50);
    g.drawArc(300,50,80,40, 135,180);

    // Again the same test, but we will fill the arc
    g.drawRect(400,50,40,80);
    g.drawLine(400,50,440,130);
    g.drawLine(400,130,440,50);
    g.setColor(Color.blue);
    g.fillArc(400,50,40,80, 135,180);
    g.setColor(Color.black);

    // Repeat again, but this time with different angles to the arc.
    // We do this to compare how Java and PDF render the arcs
    g.drawRect(400,150,40,80);
    g.drawLine(400,150,440,230);
    g.drawLine(400,230,440,150);
    g.setColor(Color.blue);
    g.fillArc(400,150,40,80, 135,225);
    g.setColor(Color.black);



    // Finally draw a small table of all the fonts and styles
    String fonts[] = new String[] {"SansSerif",
                                   "Monospaced",
                                   "TimesRoman",
                                   "Helvetica",
                                   "Courier",
                                   "Dialog",
                                   "DialogInput"};
    String modes[] = new String[] {"Plain",
                                   "Bold",
                                   "Italic",
                                   "Bold+Italic"};
    int imodes[] = new int[] {Font.PLAIN,
                              Font.BOLD,
                              Font.ITALIC,
                              Font.BOLD + Font.ITALIC};

    int ty = 170;

    for(int i=0;i<modes.length;i++)
      g.drawString(modes[i],100+(50*i),ty-14);

    FontMetrics fm = g.getFontMetrics();
    for(int i=0;i<fonts.length;i++)
      g.drawString(fonts[i],98-fm.stringWidth(fonts[i]),ty+(12*i));

    Font cf = g.getFont();

    for(int i=0;i<fonts.length;i++) {
      for(int j=0;j<modes.length;j++) {
        g.setFont(new Font(fonts[i],imodes[j],10));
        g.drawString(modes[j],100+(50*j),ty);
      }

      ty+=12;
    }*/
	} // end doSecondPage

	/**
	 * <p>The test is initiated through the main method.  From the 
	 * command line, two parameters are needed, -pdf [path-to-pdf], which 
	 * is the path and filename of the pdf you would like to create using 
	 * this test.  It should end in ".pdf".  The other param is 
	 * -img [path-to-image].  It should be a pre-existing image, preferably 
	 * a very small jpg.  The command line arg -nw, for no window test, is 
	 * not yet supported.</p>
	 *
	 * @param args a <code>String[]</code> value
	 */
	public static void main(String[] args) 
	{
		/*if ((args != null) && (args.length > 0)) 
    {
      int len = args.length;

      for (int i = 0; i < len; i++) 
      {
        if (args[i].equals("-nw"))
        {
          noWindow = true;
        }
        if (args[i].equals("-pdf")) 
        {
          if (len > (i + 1)) 
          {
            outputPdfFile = args[i + 1];
          }
        }
        if (args[i].equals("-img")) 
        {
          if (len > (i + 1)) {
            sampleImageFile = args[i + 1];
          }
        }
      }
    }
    else 
    {
      usage();
      System.exit(1);
    }
    if (outputPdfFile == null)
    {
      System.err.println("No output file specified");
      usage();
      System.exit(1);
    }
    if (sampleImageFile == null)
    {
      System.err.println("No sample image file specified");
      usage();
      System.exit(1);
    }*/

		// Params are ok, proceed with test
		new PDFTest(outputPdfFile, sampleImageFile, noWindow);

	} // end main

	private static void usage()
	{
		System.out.println("PDFTest Usage:");
		System.out.println();
		System.out.print("java -classpath <$CLASSPATH> gnu.jpdf.PDFTest -pdf ");
		System.out.print("<output-file-path> -img <path-to-image>");
		System.out.println();
		System.out.println();
		System.out.println("This will produce the pdf file generated at ");
		System.out.println("<output-file-path> (which should end in '.pdf') and ");
		System.out.println("use the image at <path-to-image>.  Use a small jpg ");
		System.out.println("preferably since the compression is not so good ");
		System.out.println("and a pdf file will typically be 10 times as big as ");
		System.out.println("the image used as a sample.");
		System.out.println();
	}
} // end class PDFTest


//Non public classes used by PDFTest

class TestPanel extends JPanel implements Scrollable 
{
	private static final long serialVersionUID = 1L;
	// Scrollable methods
	private Image image;

	public Dimension getPreferredScrollableViewportSize()
	{return getPreferredSize(); }// Not sure if this is what I want    

	public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, 
			int direction) 
	{return 20; }// This is fine, no customization needed

	public boolean getScrollableTracksViewportHeight() 
	{return false;} // true disables scrolling

	public boolean getScrollableTracksViewportWidth() 
	{return false; }// true disables scrolling

	public int getScrollableUnitIncrement(Rectangle visibleRect, 
			int orientation, 
			int direction) {
		return 5; // This is fine, no customization needed
	}

	public void setImage(Image img) {
		image = img;
	}

	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.setColor(Color.gray);
		g.fillRect(0,0,getSize().width,getSize().height);
		if (image != null) {
			g.drawImage(image, 0, 0, this);
		}    
	} // end paintComponent

} // end class TestPanel


/**
 * Really basic toolbar - not an example of the finest GUI design
 *
 */
class TestMenuBar extends JMenuBar
{
	private static final long serialVersionUID = 1L;
	JMenu file, personnel, help, view;
	JMenuItem printer;
	JMenuItem close;
	JMenuItem helpTopics;
	JMenuItem viewFirstPage;
	JMenuItem viewSecondPage;

	public TestMenuBar(ActionListener parent)
	{
		file = new JMenu("File");
		file.setMnemonic(KeyEvent.VK_F);

		printer = new JMenuItem("Print");
		printer.setMnemonic(KeyEvent.VK_R);
		printer.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, 
				ActionEvent.CTRL_MASK));
		printer.addActionListener(parent);
		//printer.setEnabled(false);
		file.add(printer);

		close = new JMenuItem("Close");
		close.setMnemonic(KeyEvent.VK_Q);
		close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 
				ActionEvent.CTRL_MASK));
		close.addActionListener(parent);
		file.add(close);    

		view = new JMenu("View");
		view.setMnemonic(KeyEvent.VK_V);

		// This isn't very extensible
		viewFirstPage = new JMenuItem("First Page");
		viewFirstPage.addActionListener(parent);
		view.add(viewFirstPage);
		viewSecondPage = new JMenuItem("Second Page");
		viewSecondPage.addActionListener(parent);
		view.add(viewSecondPage);

		help = new JMenu("Help");
		help.setMnemonic(KeyEvent.VK_H);
		helpTopics = new JMenuItem("Help Topics");
		helpTopics.addActionListener(parent);
		help.add(helpTopics);

		add(file);
		add(view);   
		add(help);
	} // end constructor
} // end class TestMenuBar

/**
 * A simple help frame.  Nothing fancy.
 *
 */
class HelpFrame extends JFrame
{
	private static final long serialVersionUID = 1L;

	public HelpFrame()
	{
		setTitle("gnupdf Help");

		Container helpContent = getContentPane();

		helpContent.setLayout(new BorderLayout());
		JTextArea textArea = new JTextArea(20, 40);
		textArea.setLineWrap(true);
		textArea.append(getHelpText());    
		JScrollPane helpScroller = new JScrollPane(textArea);
		helpContent.add(helpScroller);
		setSize(helpScroller.getSize());
		setLocation(new Point(200, 200));
		pack();
		toFront();
		setVisible(true);
		//helpScroller.getViewport().setViewPosition(new Point(0, 0));
		//textArea.scrollRectToVisible(new Rectangle(0, 0, 2, 2));
		textArea.setCaretPosition(0);
		textArea.setEditable(false);
	}

	private String getHelpText() 
	{
		StringBuffer out = new StringBuffer();
		out.append("gnujpdf Help File and Tutorial\n");
		out.append("\n");
		out.append("This file contains some general help and a simple tutorial on the\n");
		out.append("gnujpdf java package (gnu.jpdf.*).  More information can be\n");
		out.append("obtained from the website, http://gnujpdf.sourceforge.net.\n");
		out.append("\n");
		out.append("gnujpdf is a set of Java classes that allows a programmer to use\n");
		out.append("extended versions of java.awt.Graphics and java.awt.PrintJob to\n");
		out.append("generate and print pdf files.  The idea is to use methods and\n");
		out.append("classes that act on a Graphics object to produce the same output\n");
		out.append("in a pdf file, on the screen, and on the printer.\n");
		out.append("\n");
		out.append("The best source of information for a programmer wishing to use\n");
		out.append("this simple API is the source code in PDFTest.java.  It\n");
		out.append("demonstrates a simple application that displays various\n");
		out.append("formatting and simultaneously writes a pdf file that will be an\n");
		out.append("identical copy of what is seen on the screen.\n");
		out.append("\n");
		out.append("The starting point for creating any PDF document with this\n");
		out.append("library is the PDFJob class.\n");
		out.append("\n");
		out.append("PDFJob job = new PDFJob(fileOutputStream);\n");
		out.append("\n");
		out.append("The fileOutputStream is normally a stream initialized with the\n");
		out.append("name of the pdf you wish to generate, such as \"test.pdf\".  A\n");
		out.append("PDFGraphics object can be obtained from the job by calling:\n");
		out.append("\n");
		out.append("Graphics pdfGraphics = job.getGraphics();\n");
		out.append("\n");
		out.append("This Graphics object can be passed into the same methods used to\n");
		out.append("draw to the screen.  Most of the common methods in\n");
		out.append("java.awt.Graphics have been implemented (with a few important\n");
		out.append("exceptions - this is a beta product, so there is still plenty of\n");
		out.append("work to be done - see the source code for more specifics).  When\n");
		out.append("calling methods such as drawString(..)  or drawImage(..), what is\n");
		out.append("actually happening is that the PDFGraphics object is writing the\n");
		out.append("necessary markup to the output stream.\n");
		out.append("\n");
		out.append("A new pdf page is initialized by disposing of the exisiting\n");
		out.append("Graphics object and getting a new one from the job.\n");
		out.append("\n");
		out.append("pdfGraphics.dispose(); \n");
		out.append("pdfGraphics = job.getGraphics();\n");
		out.append("\n");
		out.append("Any Graphics operations will now be made on a new page in the pdf\n");
		out.append("document.  When the document is finished, the job must be closed\n");
		out.append("out:\n");
		out.append("\n");
		out.append("pdfGraphics.dispose();\n");
		out.append("job.end();\n");
		out.append("\n");
		out.append("And the fileOutputStream will need to be closed properly as well,\n");
		out.append("as this is not guaranteed to be taken care of by the PDF classes.\n");
		out.append("\n");
		out.append("----------------\n");
		out.append("End of Help File\n");
		out.append("\n");
		out.append("For more information, see http://gnujpdf.sourceforge.net\n");
		out.append("\n");
		return out.toString();
	}
} // end class HelpFrame